package com.example.ordersservice.Api;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.commonutils.JwtUtils;
import com.example.commonutils.R;
import com.example.commonutils.vo.OrderCustomerCommon;
import com.example.commonutils.vo.ShoppingCartCommon;
import com.example.ordersservice.client.CustomerClient;
import com.example.ordersservice.client.ShoppingCartClient;
import com.example.ordersservice.entity.OrderOrders;
import com.example.ordersservice.entity.VO.OrderSelectByConditionVO;
import com.example.ordersservice.service.OrderOrdersService;
import com.example.ordersservice.vo.CreateOrdersVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/ordersservice/order")
public class OrderController {
    @Autowired
    private OrderOrdersService orderOrdersService;
    @Autowired
    private ShoppingCartClient shoppingCartClient;
    @Autowired
    private CustomerClient customerClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    //订单确认列表，便于用户确认，并在前端弹出框可以添加备注信息
    @GetMapping("/showOrder")
    public R showOrder(@RequestParam List<String> ids){
        String orderDetail = "";
        for (String id : ids) {
            ShoppingCartCommon shoppingCartCommon = shoppingCartClient.queryShoppingCartInfo(id);
            String dishName = shoppingCartCommon.getDishName();
            Integer copies = shoppingCartCommon.getCopies();
            String dishNum = copies+";"+"\n";
            String subOrderDetail  = dishName +"×"+ dishNum;
            orderDetail = orderDetail + subOrderDetail;
        }
        return R.ok().data("orderDetail",orderDetail);
    }
    //生成订单
    @PostMapping("/createOrder")
    public R saveOrder(@RequestParam List<String> ids, HttpServletRequest request, @RequestBody CreateOrdersVo createOrdersVo){
        //调用jwt工具类的方法，根据request对象获取头信息，返回用户id
        String customerId = JwtUtils.getMemberIdByJwtToken(request);
        //ids是购物车中选中的某条购物车数据的id
        //同时向订单详情表插入订单详情(虽然订单表就已经可以展示详情了，但是付款后减库存必须知道订单的菜品id)
        OrderOrders orders = orderOrdersService.createOrders(ids, customerId, createOrdersVo.getNote());
        //先生成订单，再删除缓存，保证数据的一致性
        stringRedisTemplate.delete("cache:ordersAmount:"+customerId);
        Set<String> keys = stringRedisTemplate.keys("cache:orders:" + customerId + "*");
        stringRedisTemplate.delete(keys);
        return R.ok().data("orders",orders);
    }
    //根据订单流水号查询订单信息
    @GetMapping("/getOrderInfo/{ordersNumber}")
    public R getOrderInfo(@PathVariable String ordersNumber){
        LambdaQueryWrapper<OrderOrders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderOrders::getOrdersNumber,ordersNumber);
        OrderOrders order = orderOrdersService.getOne(queryWrapper);
        return R.ok().data("order",order);
    }
    //前端的订单分页查询
    //带条件的分页查询(只能查自己的订单)
    //分页插件
    @PostMapping("/selectPageByCondition/{page}/{pageSize}")
    //TODO 加上缓存后，分页跳转不了,订单被删除后，仍然被查到
    public R selectPageByCondition(@RequestBody OrderSelectByConditionVO orderSelectByConditionVO,
                                   @PathVariable int page, @PathVariable int pageSize,HttpServletRequest request){
        String customerId = JwtUtils.getMemberIdByJwtToken(request);
        log.info(customerId);
        //将查询条件也保存到redis
        String s1 = stringRedisTemplate.opsForValue().get("cache:orderSelectByConditionVO"+customerId);
        String s3 = JSONUtil.toJsonStr(orderSelectByConditionVO);
        stringRedisTemplate.opsForValue().set("cache:orderSelectByConditionVO"+customerId,s3,30,TimeUnit.MINUTES);
        //只要查询条件改变，都清空缓存，否则查询结果不发生变化
        if (!s3.equals(s1)){
            stringRedisTemplate.delete("cache:ordersAmount:"+customerId);
        }
        //查询数据，先从缓存中查询，查不到，再去数据库查
        String s = stringRedisTemplate.opsForValue().
                get("cache:orders:"+customerId+":"+ "page" + page + "pageSize" + pageSize);
        String s2 = stringRedisTemplate.opsForValue().get("cache:ordersAmount:"+customerId);
        if (s != null && s2 != null){
            List<OrderOrders> records = JSONUtil.toList(s, OrderOrders.class);
            //由于是分页查询，返回的是Page类型，所以缓存的结果也封装成该类型
            Page<OrderOrders> pageInfo = new Page<>(page,pageSize);
            pageInfo.setRecords(records);
            pageInfo.setTotal(Long.parseLong(s2));
            return R.ok().data("pageInfo",pageInfo);
        }
        //通过用户id查询用户手机号，手机号作为唯一标识
        OrderCustomerCommon customerInfoById = customerClient.getCustomerInfoById(customerId);
        String phone = customerInfoById.getPhone();
        LambdaQueryWrapper<OrderOrders> queryWrapper = new LambdaQueryWrapper<>();
        String ordersNumber = orderSelectByConditionVO.getOrdersNumber();
        String begin = orderSelectByConditionVO.getBegin();
        String end = orderSelectByConditionVO.getEnd();
        queryWrapper.eq(OrderOrders::getOrdersPhone,phone);
        queryWrapper.eq(null != ordersNumber,OrderOrders::getOrdersNumber,ordersNumber);
        queryWrapper.ge(null != begin,OrderOrders::getGmtCreate,begin);
        queryWrapper.le(null != end,OrderOrders::getGmtCreate,end);
        queryWrapper.orderByDesc(OrderOrders::getGmtCreate);
        Page<OrderOrders> pageInfo = new Page<>(page,pageSize);
        orderOrdersService.page(pageInfo,queryWrapper);
        //在数据库中查完后，再存入redis
        //将总记录数也存入redis，
        long total = pageInfo.getTotal();
        stringRedisTemplate.opsForValue().set("cache:ordersAmount:"+customerId, total+"",30,TimeUnit.MINUTES);
        List<OrderOrders> records = pageInfo.getRecords();
        stringRedisTemplate.opsForValue().set("cache:orders:"+customerId+":"+ "page" + page + "pageSize" + pageSize,
                JSONUtil.toJsonStr(records),30, TimeUnit.MINUTES);
        return R.ok().data("pageInfo",pageInfo);
    }
}
